package com.czr.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.util.*;


public class HttpClientUtil {
    public static String getResult(String url, String jo) {
        String result = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build();
        HttpPost post = new HttpPost(url);
        post.setConfig(requestConfig);
        CloseableHttpResponse response;
        try {
            if (null != jo) {
//                System.out.println("发送的请求参数 " + jo);
                post.addHeader("Content-type", "application/json; charset=utf-8");
                post.setHeader("Accept", "application/json");
                post.setEntity(new StringEntity(jo, StandardCharsets.UTF_8));
            }
            response = httpclient.execute(post);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String charset = "UTF-8";
                charset = getContentCharSet(entity);
                result = EntityUtils.toString(entity, charset);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return result;
    }

    public static String getTyResult(String url, String jo, String cookie) {
        String result = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build();
        HttpPost post = new HttpPost(url);
        post.setConfig(requestConfig);
        CloseableHttpResponse response;
        try {
            if (null != jo) {
                System.out.println("发送的请求参数 " + jo);
                post.addHeader("Content-type", "application/json; charset=utf-8");
                post.setHeader("Accept", "application/json");
                post.setHeader("authorization", "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvd3d3Lml0anV6aS5jb21cL2FwaVwvdXNlcnNcL3VzZXJfaGVhZGVyX2luZm8iLCJpYXQiOjE2MjcyODM5MTIsImV4cCI6MTYyNzQ2ODQxNCwibmJmIjoxNjI3NDYxMjE0LCJqdGkiOiIxV1NYTEExOHh4TjhpSGxjIiwic3ViIjo5NzU4OTEsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjciLCJ1dWlkIjoiek5wVmkxIn0.tMZMECFSyIIFwGxrOXy3QwvHhs30jfLv0FjF6gp5iGw");
                post.setHeader("cookie", cookie);
                post.setEntity(new StringEntity(jo, StandardCharsets.UTF_8));
            }
            response = httpclient.execute(post);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String charset = "UTF-8";
                charset = getContentCharSet(entity);
                result = EntityUtils.toString(entity, charset);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return result;
    }

    /**
     * get请求
     *
     * @return
     */
    public static String doGet(String url, Map<String, String> header) {
        try {
            HttpClient client = new DefaultHttpClient();
            //发送get请求
            HttpGet request = new HttpGet(url);
            if (header != null && !header.isEmpty()) {
                Set<Map.Entry<String, String>> entries = header.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    request.addHeader(entry.getKey(), entry.getValue());
                }
            }
            HttpResponse response = client.execute(request);

            /**请求发送成功，并得到响应**/
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                /**读取服务器返回过来的json字符串数据**/
                String strResult = EntityUtils.toString(response.getEntity(), "UTF-8");

                return strResult;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * get请求
     *
     * @return
     */
    public static String doGetByEncoding(String url, Map<String, String> header, String encoding) {
        try {
            HttpClient client = new DefaultHttpClient();
            //发送get请求
            HttpGet request = new HttpGet(url);
            if (header != null && !header.isEmpty()) {
                Set<Map.Entry<String, String>> entries = header.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    request.addHeader(entry.getKey(), entry.getValue());
                }
            }
            HttpResponse response = client.execute(request);
            if (StringUtils.isBlank(encoding)) {
                encoding = "UTF-8";
            }
            /**请求发送成功，并得到响应**/
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                /**读取服务器返回过来的json字符串数据**/
                String strResult = EntityUtils.toString(response.getEntity(), encoding);

                return strResult;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static String doGet(String url) {
        return doGet(url, null);
    }

    public static String getContentCharSet(final HttpEntity entity)
            throws Exception {

        if (entity == null) {
            throw new IllegalArgumentException("HTTP entity may not be null");
        }
        String charset = null;
        if (entity.getContentType() != null) {
            HeaderElement values[] = entity.getContentType().getElements();
            if (values.length > 0) {
                NameValuePair param = values[0].getParameterByName("charset");
                if (param != null) {
                    charset = param.getValue();
                }
            }
        }

        if (null == charset) {
            charset = "UTF-8";
        }
        return charset;
    }

    public static String getResultby(String url, String jo) {
        String result = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build();
        HttpPost post = new HttpPost(url);
        post.setConfig(requestConfig);
        CloseableHttpResponse response;
        try {
            if (null != jo) {
//                System.out.println("发送的请求参数 " + jo);
                post.addHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
                post.setHeader("Accept", "application/json");
                post.setEntity(new StringEntity(jo, StandardCharsets.UTF_8));
            }
            response = httpclient.execute(post);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String charset = "UTF-8";
                charset = getContentCharSet(entity);
                result = EntityUtils.toString(entity, charset);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return result;
    }

    public static String getResultbyGet(String url) {
        String result = "";
        CloseableHttpClient httpCilent = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)   //设置连接超时时间
                .setConnectionRequestTimeout(5000) // 设置请求超时时间
                .setSocketTimeout(5000)
                .setRedirectsEnabled(true)//默认允许自动重定向
                .build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);
        try {
            HttpResponse httpResponse = httpCilent.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                result = EntityUtils.toString(httpResponse.getEntity());//获得返回的结果
                System.out.println(result);
            } else if (httpResponse.getStatusLine().getStatusCode() == 400) {

            } else if (httpResponse.getStatusLine().getStatusCode() == 500) {

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpCilent.close();//释放资源
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static String postMap(String url, Map<String, String> map) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
            response = httpClient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return result;
    }

    private static String entityToString(HttpEntity entity) throws IOException {
        String result = null;
        if (entity != null) {
            long lenth = entity.getContentLength();
            if (lenth != -1 && lenth < 2048) {
                result = EntityUtils.toString(entity, "UTF-8");
            } else {
                InputStreamReader reader1 = new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8);
                CharArrayBuffer buffer = new CharArrayBuffer(2048);
                char[] tmp = new char[1024];
                int l;
                while ((l = reader1.read(tmp)) != -1) {
                    buffer.append(tmp, 0, l);
                }
                result = buffer.toString();
            }
        }
        return result;
    }

    /**
     * public static String doPost(String url, Map params){
     * <p>
     * BufferedReader in = null;
     * try {
     * // 定义HttpClient
     * HttpClient client = new DefaultHttpClient();
     * // 实例化HTTP方法
     * HttpPost request = new HttpPost();
     * request.setURI(new URI(url));
     * <p>
     * //设置参数
     * List<NameValuePair> nvps = new ArrayList<NameValuePair>();
     * for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
     * String name = (String) iter.next();
     * String value = String.valueOf(params.get(name));
     * nvps.add(new BasicNameValuePair(name, value));
     * <p>
     * //System.out.println(name +"-"+value);
     * }
     * request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
     * <p>
     * HttpResponse response = client.execute(request);
     * int code = response.getStatusLine().getStatusCode();
     * if(code == 200){	//请求成功
     * in = new BufferedReader(new InputStreamReader(response.getEntity()
     * .getContent(),"utf-8"));
     * StringBuffer sb = new StringBuffer("");
     * String line = "";
     * String NL = System.getProperty("line.separator");
     * while ((line = in.readLine()) != null) {
     * sb.append(line + NL);
     * }
     * <p>
     * in.close();
     * <p>
     * return sb.toString();
     * }
     * else{	//
     * System.out.println("状态码：" + code);
     * return null;
     * }
     * }
     * catch(Exception e){
     * e.printStackTrace();
     * <p>
     * return null;
     * }
     * }
     */

    public static String getContent(String url, Map<String, String> mapdata) {
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httpPost = new HttpPost(url);
        try {
            // 设置提交方式
            httpPost.addHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
            // 添加参数
            List<NameValuePair> nameValuePairs = new ArrayList<>();
            if (mapdata.size() != 0) {
                // 将mapdata中的key存在set集合中，通过迭代器取出所有的key，再获取每一个键对应的值
                Set keySet = mapdata.keySet();
                Iterator it = keySet.iterator();
                while (it.hasNext()) {
                    String k = it.next().toString();// key
                    String v = mapdata.get(k);// value
                    nameValuePairs.add(new BasicNameValuePair(k, v));
                }
            }
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
            // 执行http请求
            response = httpClient.execute(httpPost);
            // 获得http响应体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                // 响应的结果
                String content = EntityUtils.toString(entity, "UTF-8");
                return content;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "获取数据错误";
    }

    public static String doPost(String url, Map<String, String> param) {
        return doPost(url, param, null);
    }

    public static String doPost(String url, Map<String, String> param, Map<String, String> header) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "UTF-8");
                httpPost.setEntity(entity);
            }
            if (header != null && !header.isEmpty()) {
                Set<Map.Entry<String, String>> entries = header.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }


    public static String doPost2(String url,String bodyParam, Map<String, String> header) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new StringEntity(bodyParam, "UTF-8"));

            if (header != null && !header.isEmpty()) {
                Set<Map.Entry<String, String>> entries = header.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            httpPost.addHeader("Content-Type", "application/json");

            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }



    private static PoolingHttpClientConnectionManager connManager = null;


    static void init() {
        // SSL
        if (connManager == null) {
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.INSTANCE)
                    .register("https", new SSLConnectionSocketFactory(getSSLContext())).build();
            connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        }
    }


    /**
     * 访问https的网站
     */
    private static SSLContext getSSLContext() {
        // 调用ssl
        try {
            SSLContext sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[]{truseAllManager}, null);
            return sslcontext;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 重写验证方法，取消检测ssl
     */
    private static TrustManager truseAllManager = new X509TrustManager() {

        public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                throws CertificateException {

        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                throws CertificateException {

        }

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

    };

    /**
     * get请求
     *
     * @return
     */
    public static String doHttpsGet(String url, Map<String, String> header) {
        HttpClient client = null;
        HttpGet request = null;
        try {
            init();
            client = HttpClients.custom().setConnectionManager(connManager).build();
            //发送get请求
            request = new HttpGet(url);
            if (header != null && !header.isEmpty()) {
                Set<Map.Entry<String, String>> entries = header.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    request.addHeader(entry.getKey(), entry.getValue());
                }
            }
            HttpResponse response = client.execute(request);

            /**请求发送成功，并得到响应**/
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                /**读取服务器返回过来的json字符串数据**/
                String strResult = EntityUtils.toString(response.getEntity(), "UTF-8");

                return strResult;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            request.abort();
        }

        return null;
    }

    /**
     * 采集上海政府采购网地址使用
     * @param url
     * @param jsonObject
     * @return
     */
    public static JSONObject doPostByJsonObject(String url, JSONObject jsonObject) {
        HttpClient client = HttpClientBuilder.create().build();
        HttpPost post = new HttpPost(url);
        JSONObject response = null;

        try {
            StringEntity s = new StringEntity(jsonObject.toString());
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            post.setEntity(s);
            HttpResponse res = client.execute(post);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = res.getEntity();
                String result = EntityUtils.toString(entity);
                response = JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return response;
    }

}
